package editor.main;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.LinkedList;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;

import server.buscador.ANode;
import server.buscador.AStar;
import server.buscador.NodeEdge;
import server.buscador.SpaceNode;
import editor.dxf.DxfModel;
import editor.graphics.EditorMapa;
import editor.modelo.Floor;
import editor.modelo.EditorFloor;
import editor.modelo.JSONConverter;
import editor.modelo.LandMark;
import editor.modelo.ModelUtilities;
import editor.modelo.Portal;
import editor.modelo.Space;
import editor.modelo.Portal.Clase;

import java.awt.Font;


public class Main implements TableModelListener {

	private JFrame frmEditorAulas;
	private EditorMapa editorMapa;
	private FloorTableModel ftm;
	private JTable table;

	private File workingDir;
	private JLabel lblEdificio;


	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Main window = new Main();
					window.frmEditorAulas.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public Main() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		try {
			// Set System L&F
			UIManager.setLookAndFeel(
					UIManager.getSystemLookAndFeelClassName());
		} 
		catch (Exception e) {
			// handle exception
		}

		frmEditorAulas = new JFrame();
		frmEditorAulas.setTitle("Editor Aulas");
		frmEditorAulas.setBounds(100, 100, 971, 747);
		frmEditorAulas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frmEditorAulas.getContentPane().setLayout(new BorderLayout(0, 0));

		JPanel panel_1 = new JPanel();
		frmEditorAulas.getContentPane().add(panel_1, BorderLayout.NORTH);
		panel_1.setLayout(new BorderLayout(0, 0));

		JMenuBar menuBar = new JMenuBar();
		panel_1.add(menuBar, BorderLayout.CENTER);

		JMenu mnArchivo = new JMenu("Archivo");
		menuBar.add(mnArchivo);

		JMenuItem mntmAbrir = new JMenuItem("Abrir...");
		mntmAbrir.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
			}
		});
		mnArchivo.add(mntmAbrir);

		JMenuItem mntmGuardar = new JMenuItem("Guardar");
		mnArchivo.add(mntmGuardar);

		JMenuItem mntmGuardarComo = new JMenuItem("Guardar Como...");
		mnArchivo.add(mntmGuardarComo);

		JMenuItem mntmSalir = new JMenuItem("Salir");
		mnArchivo.add(mntmSalir);

		editorMapa = new EditorMapa();
		editorMapa.setBackground(new Color(255, 250, 250));
		editorMapa.setPreferredSize(new Dimension(500, 10));
		frmEditorAulas.getContentPane().add(editorMapa, BorderLayout.CENTER);

		JPanel panel = new JPanel();
		panel.setPreferredSize(new Dimension(150, 10));
		frmEditorAulas.getContentPane().add(panel, BorderLayout.EAST);
		panel.setLayout(null);

		JSlider slider = new JSlider();
		slider.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				editorMapa.setZoom(((JSlider)e.getSource()).getValue());
			}
		});
		slider.setMajorTickSpacing(50);
		slider.setPaintLabels(true);
		slider.setPaintTicks(true);
		slider.setValue(100);
		slider.setToolTipText("Zoom del editor");
		slider.setMaximum(200);
		slider.setMinimum(25);
		slider.setBounds(10, 129, 130, 60);
		panel.add(slider);

		JLabel lblZoom = new JLabel("ZOOM");
		lblZoom.setBounds(10, 107, 37, 14);
		panel.add(lblZoom);

		JButton btnGuardarPisoJSON = new JButton("Guardar Piso");
		btnGuardarPisoJSON.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int r= JOptionPane.showConfirmDialog(null, "¿Esta seguro que desea guardar los cambios? Se sobreescribirá todo lo anterior");
				if(r == JOptionPane.YES_OPTION){
					editorMapa.getSelectedFloor().checkFormat();
					JSONConverter jc = new JSONConverter(EditorFloor.class);
					System.out.println(jc.toJSONFile(editorMapa.getSelectedFloor(),	
							"./" + editorMapa.getSelectedFloor().getCompleteFloorName()+".json"));
				}
			}
		});
		btnGuardarPisoJSON.setBounds(10, 11, 119, 23);
		panel.add(btnGuardarPisoJSON);

		JButton btnCargarEdif = new JButton("CargarEdificio");
		btnCargarEdif.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				editorMapa.clean();
				JSONConverter jc = new JSONConverter(EditorFloor.class);
				JFileChooser jfc = new JFileChooser(".");
				jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
				jfc.setVisible(true);
				int returnVal = jfc.showOpenDialog(frmEditorAulas);
				if(returnVal != JFileChooser.APPROVE_OPTION) return;
				workingDir = jfc.getSelectedFile();
				ArrayList<Floor> lf  =ModelUtilities.loadBuilding(workingDir, jc);

				lblEdificio.setText(workingDir.getName());
				if(lf.size()>0){
					ftm.setPisos(lf);
					for(Floor f: lf){
						editorMapa.addPisoVisible((EditorFloor) f);
					}
				}else JOptionPane.showMessageDialog(frmEditorAulas, "No se encontró ningún archivo seleccionado de tipo .json en el directorio seleccionado.");

			}
		});
		btnCargarEdif.setBounds(10, 73, 119, 23);
		panel.add(btnCargarEdif);

		JButton btnBuscar = new JButton("Buscar");
		btnBuscar.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String s=	JOptionPane.showInputDialog("ingrese el nombre de fuente@destino y por consola se le muestra el camino. Es para debug, que queres?");
				String[] partes = s.split("@");
				AStar a = new AStar();

				ANode res = a.search(partes[0], partes[1]);
				if(res == null) {System.out.println("No existe camino");
				return;}
				System.out.println("el camino es:");
				for(SpaceNode sn : res.camino){
					System.out.print(sn.getName()+ " ");
				}
				//System.out.println(partes[1]);
			}
		});
		btnBuscar.setBounds(22, 606, 89, 23);
		panel.add(btnBuscar);

		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(0, 247, 150, 244);
		panel.add(scrollPane);



		ftm = new FloorTableModel();
		ftm.addTableModelListener(this);
		table = new JTable(ftm);
		scrollPane.setViewportView(table);

		JButton btnEditar = new JButton("Editar");
		btnEditar.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(table.getSelectedRow() >=0){
					Floor p = ftm.getFloor(table.getSelectedRow());
					editorMapa.setSelectedFloor((EditorFloor) p);
				}
			}
		});
		btnEditar.setBounds(80, 491, 60, 23);
		panel.add(btnEditar);

		lblEdificio = new JLabel("Edificio");
		lblEdificio.setHorizontalAlignment(SwingConstants.CENTER);
		lblEdificio.setFont(new Font("Times New Roman", Font.PLAIN, 14));
		lblEdificio.setBounds(10, 224, 130, 23);
		panel.add(lblEdificio);

		JButton btnNuevoPiso = new JButton("Nuevo Piso");
		btnNuevoPiso.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(workingDir == null){
					JOptionPane.showMessageDialog(frmEditorAulas, "Debe seleccionar un directorio de trabajo primero");
					return;
				}
				String s = JOptionPane.showInputDialog("Ingrese el nombre del piso");
				if(s == null) return;
				EditorFloor f = new EditorFloor();
				f.setbuildingName(workingDir.getName());
				f.setFloorName(s);
				editorMapa.setSelectedFloor(f);
				ftm.addPiso(f);
			}
		});
		btnNuevoPiso.setBounds(10, 39, 119, 23);
		panel.add(btnNuevoPiso);

		JButton btnLinkearMapas = new JButton("Generar Mapas");
		btnLinkearMapas.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
			
				int r= JOptionPane.showConfirmDialog(null, "Se sobreescribiran TODOS los mapas, se controlará el formato (corregirá), se linkearan y se generará la lista de espacios actualizada, ¿continuar?");
				if(r == JOptionPane.YES_OPTION){
					JSONConverter jc = new JSONConverter(EditorFloor.class);
					for(Floor f: ftm.getPisos()){ //guardo todo 
					//	((EditorFloor) f).checkFormat();
						jc.toJSONFile(f,	
								"./" + f.getCompleteFloorName()+".json");
					}
					LinkedList<String> aulas = new LinkedList<String>();
					ArrayList<Floor> pisos = ModelUtilities.loadBuilding(workingDir, jc); //linkea
					for (Floor f : pisos) { //genera lista de aulas
						for(Space sp: f.getEspacios()){
							aulas.add(sp.getName());
						}
						for(LandMark lm: f.getLandmarks()){
							aulas.add(lm.getName());
						}
					}
					ModelUtilities.saveSpaceList(aulas, workingDir);
					for(Floor f: ftm.getPisos()){ //vuelvo a guardar linkeado
						((EditorFloor) f).checkFormat();
						jc.toJSONFile(f,	
								"./" + f.getCompleteFloorName()+".json");
					}
					ArrayList<Floor> lf  =ModelUtilities.loadBuilding(workingDir, jc);

					//lblEdificio.setText(workingDir.getName());
					if(lf.size()>0){
						editorMapa.clean();
						ftm.setPisos(lf);
						for(Floor f: lf){
							editorMapa.addPisoVisible((EditorFloor) f);
						}
					}
				}
				editorMapa.repaint();
				}
			
		});
		btnLinkearMapas.setBounds(22, 632, 107, 23);
		panel.add(btnLinkearMapas);
		
		JButton btndxf = new JButton("Dxf");
		btndxf.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if(table.getSelectedRow() >=0){
					Floor p = ftm.getFloor(table.getSelectedRow());
					String s=	JOptionPane.showInputDialog("ingrese la escala del mapa.. ¿250, 200, etc?");
					String s2=	JOptionPane.showInputDialog("ingrese la rotacion del mapa.. ¿90, -90, etc?");
					DxfModel mod = new DxfModel(workingDir+"/"+p.getFloorName()+".dxf", Integer.valueOf(s), Integer.valueOf(s2));
					editorMapa.setFondo(mod);
					editorMapa.repaint();
				}
				
			}
		});
		btndxf.setBounds(80, 515, 60, 23);
		panel.add(btndxf);

	}

	@Override
	public void tableChanged(TableModelEvent e) {
		if(ftm.getRowCount()== 0)return;
		int a = e.getFirstRow();
		if((Boolean) ftm.getValueAt(a, 1)){ //si esta seleccionado
			editorMapa.addPisoVisible((EditorFloor) ftm.getFloor(a));
		} else
			editorMapa.removePisoVisible((EditorFloor) ftm.getFloor(a));
		editorMapa.repaint();

	}
}

